package com.algorithm.hqy.practice;

import com.algorithm.hqy.ArrayStack;
import com.algorithm.hqy.LinkedListStack;
import com.sun.xml.internal.ws.util.StringUtils;

import java.util.Scanner;

/**
 * @Classname InfixPractice
 * @Date 2019/9/18 16:36
 * @auther by hqy
 */
public class InfixPractice {

    static String input = null;

    public static int getPiority(char c) {
        Operator[] enumName = Operator.values();
        for (Operator operator : enumName) {
            if (operator.getValue() == c) {
                return operator.pioirty;
            }
        }
        return -1;
    }


    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        input = scanner.next();

        ArrayStack numStack = new ArrayStack(input.length(), String.class);
        ArrayStack operatroStack = new ArrayStack(input.length() / 2, String.class);

        char operator = ' ';
        while (input != "" && input != null) {
            String cal = getElement();
            if (isCalNumber(cal)) {
                numStack.push(cal);
            } else if (!operatroStack.isEmpty() && getPiority(cal.charAt(0)) <=
                    getPiority(((String) operatroStack.peek()).charAt(0))) {
                stackCal(numStack, operatroStack, cal.charAt(0));
                operatroStack.push(cal);
            } else {
                operatroStack.push(cal);
            }

        }
        while (true) {
            if (operatroStack.isEmpty()) {
                break;
            }
            operator = ' ';
            stackCal(numStack, operatroStack, operator);
        }

        System.out.println("最终结果为：" + numStack.pop());
    }

    public static void stackCal(ArrayStack numberStack, ArrayStack operatorStack, char operator) {

        String num1;
        String num2;
        double sum = 0;


        if (operator != ' ') {
            while (true) {
                if (!operatorStack.isEmpty() && getPiority(operator) <=
                        getPiority(((String) operatorStack.peek()).charAt(0))) {
                    num1 = (String) numberStack.pop();
                    num2 = (String) numberStack.pop();
                    char tempOperator= ((String) operatorStack.pop()).charAt(0);
                    sum = cal(num2, num1, tempOperator);

                    numberStack.push(String.valueOf(sum));
                } else {
                    break;
                }
            }


        } else {

            num1 = (String) numberStack.pop();
            num2 = (String) numberStack.pop();
            operator = ((String) operatorStack.pop()).charAt(0);
            sum = cal(num2, num1, operator);

            numberStack.push(String.valueOf(sum));
        }


    }


    public static boolean isCalNumber(String s) {
        if (s.equals("+") || s.equals("/") || s.equals("*") || s.equals("-")) {
            return false;
        } else {
            return true;
        }
    }

    public static String getElement() {
        char[] valueChar = input.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < input.length(); i++) {
            if (valueChar[i] == 42 || valueChar[i] == 43 || valueChar[i] == 45 || valueChar[i] == 47) {
                if (sb.length() > 0) {
                    input = input.substring(sb.length());
                    return sb.toString();
                }
                input = input.substring(1);
                return String.valueOf(valueChar[i]);
            } else {
                sb.append(valueChar[i]);
            }
        }
        input = "";
        return sb.toString();
    }

    public static double cal(String num1, String num2, char c) {
        switch (c) {
            case '+':
                return Double.valueOf(num1) + Double.valueOf(num2);
            case '-':
                return Double.valueOf(num1) - Double.valueOf(num2);
            case '*':
                return Double.valueOf(num1) * Double.valueOf(num2);
            case '/':
                return Double.valueOf(num1) / Double.valueOf(num2);
        }
        throw new RuntimeException("wrong operator");
    }


    public static void validate(String expr) {
        char[] expression = expr.toCharArray();

        for (int i = 0; i < expr.length(); i++) {
            if (!isEffective(expression[i])) {
                throw new RuntimeException("表达式不合法");
            }
        }
    }

    private static boolean isEffective(char c) {
        if ((c >= 48 && c <= 57) || c == 42 || c == 43 || c == 45 || c == 47) {
            return true;
        } else {
            return false;
        }
    }


}

enum Operator {

    PLUSE('+'),
    MUTIPLY('*'),
    SUBTRACT('-'),
    DIVIDED('/');
    char value;
    int pioirty;

    Operator(char value) {
        this.value = value;
        if (value == '+' || value == '-') {
            this.pioirty = 0;
        } else {
            this.pioirty = 1;
        }
    }

    public char getValue() {
        return this.value;
    }
}
